#include "ViewCamera.h"
#include <QDebug>

ViewCamera::ViewCamera()
    : m_eye(0.0f, 0.0f, 70.0f), // 请保证相机初始位置所有分量为正，否则会发生抖动现象
    m_center(0.0f, 0.0f, 0.0f),
    m_up(0.0f, 1.0f, 0.0f),
    m_fov(45.0f)
{
    lookAt(m_eye, m_center, m_up);
}

void ViewCamera::setPerspective(float aspect, float nearPlane, float farPlane)
{
    m_projection.setToIdentity();
    m_projection.perspective(m_fov, aspect, nearPlane, farPlane);
}

void ViewCamera::lookAt(const QVector3D &eye, const QVector3D &center, const QVector3D &up)
{
    m_eye = eye;
    m_center = center;
    m_up = up;
    m_view.setToIdentity();
    m_view.lookAt(m_eye, m_center, m_up);
}

void ViewCamera::setMouseLockedStatus(bool locked)
{
    m_mouseLocked = locked;
}

void ViewCamera::setSensitivity(float mouse_sensitivity)
{
    if(mouse_sensitivity >= 0.0f)
        m_sensitivity = mouse_sensitivity;
    else
        qDebug()<< "Invalid mouse sensitivity value.";
}

void ViewCamera::surroundOriginByMouseInput(const QPoint &mouseDelta) {
    if (m_mouseLocked) return;

    // 1. 计算增量旋转（弧度），灵敏度建议(0.1f ~ 0.5f)
    float deltaYaw = -mouseDelta.x() * m_sensitivity * 0.01f;
    float deltaPitch = -mouseDelta.y() * m_sensitivity * 0.01f;

    // 2. 获取当前相机方向向量
    QVector3D forward = (m_center - m_eye).normalized();
    QVector3D right = QVector3D::crossProduct(forward, m_up).normalized();
    QVector3D up = QVector3D::crossProduct(right, forward);

    // 3. 应用增量旋转（四元数）
    QQuaternion yawRot = QQuaternion::fromAxisAndAngle(up, deltaYaw * 180.0f / M_PI);
    QQuaternion pitchRot = QQuaternion::fromAxisAndAngle(right, deltaPitch * 180.0f / M_PI);
    QQuaternion totalRot = pitchRot * yawRot;  // 先偏航，后俯仰

    // 4. 更新相机位置
    float radius = m_eye.distanceToPoint(m_center);
    QVector3D newEye = m_center - totalRot.rotatedVector(forward) * radius;
    m_eye = newEye;

    // 5. 更新 up 向量（防止万向节锁）
    m_up = totalRot.rotatedVector(m_up);

    // 6. 更新视图矩阵
    m_view.setToIdentity();
    m_view.lookAt(m_eye, m_center, m_up);
}

void ViewCamera::mousePressEvent(QMouseEvent *event)
{

}

void ViewCamera::mouseMoveEvent(QMouseEvent *event)
{

}

void ViewCamera::mouseReleaseEvent(QMouseEvent *event)
{

}

void ViewCamera::wheelEvent(QWheelEvent *event) {
    // 获取滚轮滚动的角度
    QPoint angleDelta = event->angleDelta();

    // 根据滚轮滚动的方向调整 FOV
    float fovDelta = angleDelta.y() > 0 ? -2.0f : 2.0f; // 滚轮向上滚动减小 FOV，向下滚动增大 FOV
    m_fov += fovDelta;

    // 限制 FOV 的范围（例如 10° 到 120°）
    if (m_fov < 10.0f) m_fov = 10.0f;
    if (m_fov > 120.0f) m_fov = 120.0f;
}

QMatrix4x4 ViewCamera::getViewMatrix() const
{
    return m_view;
}

QMatrix4x4 ViewCamera::getProjectionMatrix() const
{
    return m_projection;
}
